"""
This is a module for dealing with MediaWiki (generally) and Wikipedia (specifically) namespace related operations.

If you want to use this, you must add its location to your PYTHONPATH. Add these lines to your .cshrc, where you replace the second half 
of the assignment in the first line with the path to your wp-health project folder. $HOME is a reference to your home directory.

	set PROJECT = ${HOME}/workspace/wp-health/

	if ! ($?PYTHONPATH) then
		setenv PYTHONPATH ${PROJECT}/src/python/modules/
	endif

	setenv PYTHONPATH ${PYTHONPATH}:${PROJECT}/src/python/modules/
		
"""

class Namespace(object):
	"""
	Class representing a single MediaWiki or Wikipedia namespace and some of its simple properties.

	This class is used for a compact representation of a namespace. Clients should not instantiate this class.
	That is, if you ever find yourself instantiating this class, you're probably doing something wrong and should edit this module instead.
	"""
	
	def __init__(self, name, index, isTalk, isSystem, isUsed):
		"""
		Called upon construction of a Namespace object. All constructor arguments are required for the sake of completeness.

		name: the lowercase, space separated version of the name of the namespace (i.e. Main is 'main', User Talk is 'user talk', etc)
		index: the numerical index of the namespace as indicated by http://en.wikipedia.org/wiki/Wikipedia:Namespace
		isTalk: whether the namespace is for talk (this should be obvious by its content)
		isSystem: whether the namespace is used by the MediaWiki software specifically for system tasks (e.g. 'special', 'media' namespaces)
		isUsed: whether the namespace is currently used by wikipedia (e.g. 'course', 'institution' namespaces) - this will change over time
		"""
		object.__init__(self)
		self.name = name
		self.index = index
		self.isTalk = isTalk
		self.isSystem = isSystem
		self.isUsed = isUsed

	def __eq__(self, other):
		"""
		Compares equality of two namespace objects. They are equal if and only if they have the same index.
		"""
		return self.index == other.index

	def __ne__(self, other):
		"""
		Compares inequality of two namespace objects. They are equal if and only if they have the same index.
		"""
		return not self.__eq__(self, other)

	def __lt__(self, other):
		"""
		Compares magnitude of two namespace objects with the < operator. A < B if and only if A's index is less than B's index.
		"""
		return self.index < other.index

	def __gt__(self, other):
		"""
		Compares magnitude of two namespace objects with the > operator. A > B if and only if A's index is greater than B's index.
		"""
		return self.index > other.index

	def __le__(self, other):
		"""
		Compares magnitude of two namespace objects with the <= operator. A <= B if and only if A < B or A == B.
		"""
		return self.__lt__(self, other) or self.__eq__(self, other)

	def __ge__(self, other):
		"""
		Compares magnitude of two namespace objects with the >= operator. A >= B if and only A > B or A == B.
		"""
		return self.__gt__(self, other) or self.__eq__(self, other)
	

special = Namespace('special', -1, False, True, False)
"""
Class representing the Special MediaWiki system namespace. This namespace should never appear in dump data and is included here for completeness.
This namespace is for system generated pages e.g. the Recent Changes page.
"""

media = Namespace('media', -2, False, True, False)
"""
Class representing the Media MediaWiki system namespace. This namespace should never appear in dump data and is included here for completeness.
This namespace is for direct links to hosted files in MediaWiki.
"""

main = Namespace('main', 0, False, False, True)
"""
Class representing the Main namespace, a default MediaWiki namespace.
This namespace is for article content in Wikipedia.
"""

talk = Namespace('talk', 1, True, False, True)
"""
Class representing the Main Talk namespace, a default MediaWiki namespace.
This namespace is for discussion about articles in Wikipedia.
"""

user = Namespace('user', 2, False, False, True)
"""
Class representing the User namespace, a default MediaWiki namespace.
This namespace is for information about users in Wikipedia.
"""

user_talk = Namespace('user talk', 3, True, False, True)
"""
Class representing the User Talk namespace, a default MediaWiki namespace.
This namespace is for discussion about and with users in Wikipedia.
"""

project = Namespace('project', 4, False, False, True)
"""
Class representing the Project namespace, a default MediaWiki namespace. This namespace is also aliased as Wikipedia or WP in Wikipedia.
This namespace is for information about the encyclopedia and policy in Wikipedia.
"""

project_talk = Namespace('project talk', 5, True, False, True)
"""
Class representing the Project Talk namespace, a default MediaWiki namespace. This namespace is also aliased as Wikipedia Talk or WT in Wikipedia.
This namespace is for discussion about pages about the encyclopedia and policy in Wikipedia.
"""

file = Namespace('file', 6, False, False, True)
"""
Class representing the File namespace, a default MediaWiki namespace. This namespace is also aliased as Image in Wikipedia.
This namespace is for pages about hosted files in Wikipedia.
"""

file_talk = Namespace('file talk', 7, True, False, True)
"""
Class representing the File Talk namespace, a default MediaWiki namespace. This namespace is also aliased as Image Talk in Wikipedia.
This namespace is for discussion about pages for hosted files in Wikipedia.
"""

mediawiki = Namespace('mediawiki', 8, False, False, True)
"""
Class representing the MediaWiki namespace, a default MediaWiki namespace.
This namespace is for administrators to access the MediaWiki software in Wikipedia.
"""

mediawiki_talk = Namespace('mediawiki talk', 9, True, False, True)
"""
Class representing the MediaWiki namespace, a default MediaWiki namespace.
This namespace is for all users to discuss administrator access to the MediaWiki software in Wikipedia.
"""

template = Namespace('template', 10, False, False, True)
"""
Class representing the Template namespace, a default MediaWiki namespace.
This namespace is for templates for pages in Wikipedia.
"""

template_talk = Namespace('template talk', 11, True, False, True)
"""
Class representing the Template Talk namespace, a default MediaWiki namespace.
This namespace is for discussion about template pages in Wikipedia.
"""

help = Namespace('help', 12, False, False, True)
"""
Class representing the Help namespace, a default MediaWiki namespace.
This namespace is for information about how to use the site in Wikipedia.
"""

help_talk = Namespace('help talk', 13, True, False, True)
"""
Class representing the Help Talk namespace, a default MediaWiki namespace.
This namespace is for discussion about user help pages in Wikipedia.
"""

category = Namespace('category', 14, False, False, True)
"""
Class representing the Category namespace, a default MediaWiki namespace.
This namespace is for information about the different kinds of articles and their topics in Wikipedia.
"""

category_talk = Namespace('category talk', 15, True, False, True)
"""
Class representing the Category Talk namespace, a default MediaWiki namespace.
This namespace is for discussion about category pages in Wikipedia.
"""

portal = Namespace('portal', 100, False, False, True)
"""
Class representing the Portal namespace, a custom Wikipedia namespace.
This namespace is for directories to external reference information on a certain topic.
This namespace is used as of July 2012.
"""

portal_talk = Namespace('portal talk', 101, True, False, True)
"""
Class representing the Portal Talk namespace, a custom Wikipedia namespace.
This namespace is for discussion on Portal pages.
This namespace is used as of July 2012.
"""

book = Namespace('book', 108, False, False, True)
"""
Class representing the Book namespace, a custom Wikipedia namespace.
This namespace is for open books made on Wikipedia on various topics.
This namespace is used as of July 2012.
"""

book_talk = Namespace('book talk', 109, True, False, True)
"""
Class representing the Book Talk namespace, a custom Wikipedia namespace.
This namespace is for discussion about open books on Wikipedia.
This namespace is used as of July 2012.
"""

course = Namespace('course', 442, False, False, False)
"""
Class representing the Course namespace, a custom Wikipedia namespace.
This namespace is for online classes on Wikipedia.
This namespace is not used as of July 2012.
"""

course_talk = Namespace('course talk', 443, True, False, False)
"""
Class representing the Course Talk namespace, a custom Wikipedia namespace.
This namespace is for discussion about online Wikipedia classes.
This namespace is not used as of July 2012.
"""

institution = Namespace('institution', 444, False, False, False)
"""
Class representing the Institution namespace, a custom Wikipedia namespace.
This namespace is for educational insitutions that participate in Wikipedia online classes.
This namespace is not used as of July 2012.
"""

institution_talk = Namespace('institution talk', 445, True, False, False)
"""
Class representing the Institution talk namespace, a custom Wikipedia namespace.
This namespace is for discussion about educational institutions that participate in Wikipedia online classes.
This namespace is not used as of July 2012.
"""

namespaces = [special, media, main, talk, user, user_talk, project, project_talk, file, file_talk, mediawiki, mediawiki_talk, template, template_talk, help, help_talk, category, category_talk, portal, portal_talk, book, book_talk, course, course_talk, institution, institution_talk]
"""
A list of all the namespaces in Wikipedia. Clients should not access this list directly.
If you add new namespaces to this module, make sure to add them to this list, or the module static methods will not know about them.
"""

def all_namespaces():
	"""
	Returns a list of all namespaces in Wikipedia in no particular order.
	"""
	out = []
	for namespace in namespaces:
		out.append(namespace)
	return out

def system_namespaces():
	"""
	Returns a list of all reserved system namespaces used by MediaWiki in no particular order.
	This list should be complementary to that returned by common_namespaces().
	"""
	out = []
	for namespace in namespaces:
		if namespace.isSystem:
			out.append(namespace)
	return out

def common_namespaces():
	"""
	Returns a list of all namespaces that are edited by users of MediaWiki in Wikipedia in no particular order.
	This list should be complementary to that returned by system_namespaces().
	"""
	out = []
	for namespace in namespaces:
		if not namespace.isSystem:
			out.append(namespace)
	return out

def used_namespaces():
	"""
	Returns a list of all namespaces that are currently in use by editors in Wikipedia in no particular order.
	This list should be complementary to that returned by unused_namespaces().
	"""
	out = []
	for namespace in namespaces:
		if namespace.isUsed:
			out.append(namespace)
	return out

def unused_namespaces():
	"""
	Returns a list of all namespaces that are currently not in use by editors in Wikipedia in no particular order.
	This list should be complementary to that returned by used_namespaces().
	"""
	out = []
	for namespace in namespaces:
		if not namespace.isUsed:
			out.append(namespace)
	return out

def content_namespaces():
	"""
	Returns a list of all namespaces that contain primary content on Wikipedia (i.e. not talk), excluding system namespaces, in no particular order.
	"""
	out = []
	for namespace in common_namespaces():
		if not namespace.isTalk:
			out.append(namespace)
	return out

def talk_namespaces():
	"""
	Returns a list of all namespaces that are for discussion on Wikipedia, in no particular order.
	"""
	out = []
	for namespace in namespaces:
		if namespace.isTalk:
			out.append(namespace)
	return out

def by_name(name):
	"""
	Returns the Namespace class corresponding to the given name, or None if not matched to an existing namespace.

	name: The space-separated name of a namespace to look up.
	"""
	name = name.lower()
	for namespace in namespaces:
		if namespace.name == name:
			return namespace
	return None

def by_index(index):
	"""
	Returns the Namespace class corresponding to the given index, or None if not matched to an existing namespace.

	index: The integer index of a namespace to look up.
	"""
	for namespace in namespaces:
		if namespace.index == index:
			return namespace
	return None

def name_to_index(name):
	"""
	Returns the integer index of the namespace that corresponds to the given name, or None if not matched to an existing namespace.

	name: The space-separated name of a namespace to retrieve the index of.
	"""
	namespace = by_name(name.lower())
	if namespace is None:
		return None
	return namespace.index

def index_to_name(index):
	"""
	Returns the space-separated name of the namespace that corresponds to the given integer index, or None if not matched to an existing namespace.

	index: The integer index of a namespace to retrieve the name of.
	"""
	namespace = by_index(index)
	if namespace is None:
		return None
	return namespace.name
